-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Fix #3548: Match MathTex subscripts/superscripts by position #4457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix #3548: Match MathTex subscripts/superscripts by position #4457
Conversation
…ition Use geometric matching for script elements to handle LaTeX reordering while preserving sequential matching for non-script elements.
for more information, see https://pre-commit.ci
|
Thanks for the PR. I have tried to run your new test without the suggested changes to the Similarly I have tested the full PR on the two scenes ( |
|
@henrikmidtiby Thanks for pointing that out. I had initially overlooked the fix, and since the test passed, I missed verifying whether the original issue was actually resolved. I’ve now updated the test and revised my approach. The test correctly fails on the main branch now. |
for more information, see https://pre-commit.ci
|
Good progress. I have tried to apply the current PR to the following test case (from #3548) Which renders as shown here.
Which is more consistent than if I render the scene using the current main branch, that produces this output.
I still think that the coloring is off in both cases, as I would expect the summation signs to be blue. In addition I wonder if it is possible to extract some of the functionality into a separate method. The intention here is to make it easier to understand what the code is actually doing. |
@henrikmidtiby does it look correct now?
|
|
@Nikhil172913832 Much better! |
…_break_up_by_substrings function to improve understandability
for more information, see https://pre-commit.ci
|
@henrikmidtiby I’ve made the necessary changes related to the colors. Please let me know if everything looks good. |
|
@henrikmidtiby,, addressing your first issue: In the original line: txts = [Text(sub.get_tex_string(), t2c=t2cm, **font) for sub in (eq1, eq2) for i in range(len(sub))]the expression for sub in (eq1, eq2) iterates over the MathTex objects themselves rather than their submobjects. Meanwhile, for i in range(len(sub)) loops over the number of submobjects, but Text(sub.get_tex_string(), ...) still calls .get_tex_string() on the full object instead of each submobject. A better approach would be: from manim import *
class MinimalWithSumDifficult(Scene):
def construct(self):
t2cm = {r'\sum': BLUE, '^n': RED, '_1': GREEN, 'x': YELLOW}
eq1 = MathTex(r'\sum', '^n', '_1', 'x', '^2', '= n_2', tex_to_color_map=t2cm)
eq2 = MathTex(r'\sum', '_1', '^n', 'x', '^2', '= n_2', tex_to_color_map=t2cm)
font = {'font_size': 24}
# convert each submobject to Text, arrange horizontally
def make_text_group(eq):
txts = [Text(str(mob.tex_string), t2c=t2cm, **font) for mob in eq]
for i, t in enumerate(txts):
t.next_to(txts[i - 1], RIGHT, buff=0.1) if i > 0 else None
return VGroup(*txts)
txt1 = make_text_group(eq1)
txt2 = make_text_group(eq2)
cap1 = Text('TeX rendered', **font)
cap2 = Text('TeX substrings', **font)
grp = VGroup(
cap1, cap2,
eq1, txt1,
eq2, txt2
).arrange_in_grid(rows=3, cols=2, buff=0.6)
grp.move_to(ORIGIN)
self.add(grp) |
…ing scripts, ensuring both subscript and superscript limits are displayed for integrals
6c84a90 to
adc71b4
Compare
for more information, see https://pre-commit.ci
|
@henrikmidtiby, addressing your second issue: MathTex("\\int{{_a}}^b dx = b - a")was missing the upper limit After looking into it, I found that the base element I added a check to skip the base+scripts logic if the base element’s Now: from manim import *
class MathTexUnexpectedBehaviour(Scene):
def construct(self):
t = MathTex("\\int^b{{_a}} dx = b - a")
self.add(t)
t[1].set_color(RED) |
|
@Nikhil172913832 I used some time to search for an example where the PR would fail. I don't know if it is possible to make this work for all potential cases, without reimplementing most parts of the external latex parser. I don't think that would be worth the effort though. In search of an alternative, I managed to to find a post in the #dev-chat on the manim discord server, where Benjamin Hackl mentioned a potentially more stable approach some time ago. |
|
@henrikmidtiby Thanks for the detailed feedback and for sharing that Discord thread. I agree — handling every TeX edge case isn’t practical without deeper parsing. It makes sense to wait for the \special{dvisvgm:raw} approach rather than adding a temporary fix. |








Overview: What does this pull request change?
Fixes issue where
MathTexsubmobjects did not correctly correspond to theirtex_stringswhen using subscripts and superscripts in different orders. The fix uses geometric position matching specifically for script elements (^,_) to handle LaTeX's reordering while preserving sequential matching for non-script elements.Motivation and Explanation: Why and how do your changes improve the library?
Problem: LaTeX compiles expressions like
A ^n _1andA _1 ^nto identical SVG output where subscripts and superscripts may appear in a different order than specified. This causedMathTex('A', '^n', '_1')andMathTex('A', '_1', '^n')to have submobjects that didn't match their originaltex_strings, breaking operations likeget_parts_by_tex()andset_color_by_tex().Solution: Modified
_break_up_by_substrings()method to detect script elements (tex strings starting with^or_) and match them to rendered submobjects based on geometric position (center point). Non-script elements continue using sequential matching to maintain backward compatibility and avoid issues with complex formulas.Impact: Users can now reliably access and manipulate subscripts/superscripts by their tex strings regardless of the order they're specified.
Links to added or changed documentation pages
No documentation changes required.
Further Information and Comments
MathTexmay not correspond to their tex strings #3548test_texmobject.py)test_tex_strings_with_subscripts_and_superscripts()Reviewer Checklist